using AutoMapper;
using net_work.Common;
using net_work.Common.Request;
using net_work.Common.Result;
using net_work.Data.DTO.Cou;
using net_work.Data.Entity.Cou;
using net_work.Data.Enum.Cou;
using net_work.IRepository.Cou;
using net_work.IRepository.Sys;
using net_work.IService.Cou;

namespace net_work.Service.Cou;

public class EnrollmentService(
    IMapper mapper,
    IUserContext userContext,
    IUserRepository userRepository,
    IStudentRepository studentRepository,
    IEnrollmentRepository enrollmentRepository,
    ITeachingRepository teachingRepository,
    IScheduleRepository scheduleRepository)
    : IEnrollmentService
{
    public Task<PagedResult<Enrollment>> GetEnrollmentsPagedAsync(PagedRequest request)
    {
        return enrollmentRepository.GetPagedAsync(request);
    }

    public Task<Enrollment?> SelectByIdAsync(long enrollmentId)
    {
        return enrollmentRepository.GetByIdAsync(enrollmentId);
    }

    public async Task<long> InsertEnrollment(EnrollmentAddRequest enrollmentAddRequest)
    {
        // 验证教学记录
        var teaching = await teachingRepository.GetByIdAsync(enrollmentAddRequest.TeachId);
        if (teaching is not { TeachStatus: TeachStatus.Release })
        {
            return -1;
        }
        
        // 获取学生信息
        var student = await studentRepository.GetStudentPagedAsync(new PagedRequest(1, PageSizeEnum.Unlimited,
            [new FilterCondition("UserId", FilterOperator.Equals, userContext.UserId)]));
        if (student.TotalRecords <= 0)
        {
            return -1;
        }

        var studentId = student.Data.First().Id;

        if (await ValidateEnrollment(enrollmentAddRequest.TeachId, studentId) < 0)
        {
            return -1;
        }

        var enrollmentAddRequestBackend = mapper.Map<EnrollmentAddRequestBackend>(enrollmentAddRequest);
        enrollmentAddRequestBackend.StudentId = studentId;
        // 插入选课记录
        return await enrollmentRepository.InsertAsync(enrollmentAddRequestBackend);
    }

    public async Task<int> UpdateEnrollment(EnrollmentUpdateRequest enrollmentUpdateRequest)
    {
        if (enrollmentUpdateRequest.Id <= 0)
        {
            return -1;
        }

        // 验证教学记录
        var teaching = await teachingRepository.GetByIdAsync(enrollmentUpdateRequest.TeachId);
        if (teaching is not { TeachStatus: TeachStatus.Release })
        {
            return -1;
        }
        
        // 获取学生信息
        var student = await studentRepository.GetStudentPagedAsync(new PagedRequest(1, PageSizeEnum.Unlimited,
            [new FilterCondition("UserId", FilterOperator.Equals, userContext.UserId)]));
        if (student.TotalRecords <= 0)
        {
            return -1;
        }

        var studentId = student.Data.First().Id;

        if (await ValidateEnrollment(enrollmentUpdateRequest.TeachId, studentId) < 0)
        {
            return -1;
        }

        var enrollmentUpdateRequestBackend = mapper.Map<EnrollmentUpdateRequestBackend>(enrollmentUpdateRequest);
        enrollmentUpdateRequestBackend.StudentId = studentId;
        return await enrollmentRepository.UpdateAsync(enrollmentUpdateRequestBackend) ? 1 : -1;
    }

    public async Task<int> DeleteEnrollmentByIds(List<long> ids)
    {
        foreach (var id in ids)
        {
            var enrollment = await enrollmentRepository.GetByIdAsync(id);
            if (enrollment == null)
            {
                continue;
            }

            var teaching = await teachingRepository.GetByIdAsync(enrollment.TeachId);
            if (teaching == null)
            {
                return -1;
            }

            if (teaching.TeachStatus == TeachStatus.UnRelease)
            {
                return -1;
            }
        }

        return await enrollmentRepository.DeleteByIdsAsync(ids) ? 1 : -1;
    }

    private async Task<int> ValidateEnrollment(long teachId, long studentId)
    {
        // 获取新的课程安排
        var newSchedules = await scheduleRepository.GetPagedAsync(new PagedRequest(1, PageSizeEnum.Unlimited,
            [new FilterCondition("TeachId", FilterOperator.Equals, teachId)]));
        if (newSchedules.TotalRecords <= 0)
        {
            return -1;
        }

        // 获取学生已选课程安排
        var enrollmentPagedResult = await enrollmentRepository.GetPagedAsync(new PagedRequest(1, PageSizeEnum.Unlimited,
            [new FilterCondition("StudentId", FilterOperator.Equals, studentId)]));
        var enrollmentTeachIds = enrollmentPagedResult.Data.Select(x => x.TeachId).Cast<object>().ToList();

        var oldSchedules = await scheduleRepository.GetPagedAsync(new PagedRequest(1, PageSizeEnum.Unlimited,
            [new FilterCondition("TeachId", FilterOperator.In, enrollmentTeachIds)]));

        if (oldSchedules.TotalRecords <= 0)
        {
            return 1;
        }

        // 检查新选课与旧选课是否有时间冲突
        var oldScheduleGroups = oldSchedules.Data
            .GroupBy(s => s.WeekDay)
            .ToDictionary(g => g.Key, g => g.SelectMany(s => s.ClassNumbers).ToHashSet());

        foreach (var newSchedule in newSchedules.Data)
        {
            if (!oldScheduleGroups.TryGetValue(newSchedule.WeekDay, out var oldClassNumbers))
            {
                continue;
            }

            var conflict = newSchedule.ClassNumbers.Any(cn => oldClassNumbers.Contains(cn));
            if (conflict)
            {
                return -1; // 冲突，返回失败
            }
        }

        return 1;
    }
}